﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Models.Common;
using Models.Device;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection.Metadata;
using System.Web;
using Newtonsoft.Json;
using GatewayServerService.Data;
using GatewayServerService.Mq;
using static Models.Common.EnumDeviceType;
using UtilsCache;
using UtilsORM;
using UtilsORM.MySqlData;
using GatewayServerService.CloudCenter;

namespace GatewayServerService.CloudCenter
{
    public class ServiceCloudDeviceCommand
    {


        static string logSave = UtilAppsettingCache.getSetting("base:logSave");


        /// <summary>
        /// 执行日志 new ServiceCloudDeviceCommand().writeCommandLog(commandLogModel);
        /// </summary>
        /// <param name="commandLogModel"></param>
        /// <returns></returns>
        public bool writeCommandLog(MQReqModel<object> httpReqModel)
        {

            //是否开启mq日志记录，保护emmc寿命
            if (logSave == "false")
            {
                return false;
            }

            EFYihongIotContext ef = new EFYihongIotContext();
            EFYihongIotContext efdc = new EFYihongIotContext();
            MySqlYihongIot mysqlgw = new MySqlYihongIot();
            try
            {
                ModelReceverData modelDeviceData = httpReqModel.toServerData;
                CommandLogModel commandLogModel = httpReqModel.toGatewayData;

                //0待执行,1处理中，2回调成功，3异常,4已发送mq,5mq发送失败
                int logStatus = 2;
                if (httpReqModel.respCode == ResponseCode.SUCCESS)
                {
                    logStatus = 2;
                }
                else
                {//失败
                    logStatus = 3;
                }

                string result = "";
                if (modelDeviceData != null)
                {
                    result = JsonConvert.SerializeObject(modelDeviceData);
                }
                List<iot_device_command_haddleing> haddleings = ef.iot_device_command_haddleing.Where(c => c.l_guid == commandLogModel.guid).ToList();
                foreach (iot_device_command_haddleing haddleing in haddleings)
                {
                    ///----------------写日志
                    iot_device_command_log log = new iot_device_command_log();
                    log.l_guid = haddleing.l_guid;
                    log.l_d_guid = haddleing.l_d_guid;
                    log.l_content = haddleing.l_content;
                    log.l_key = haddleing.l_key;
                    log.l_name = haddleing.l_name;
                    log.l_status_remark = httpReqModel.respMsg;
                    log.l_status = logStatus;
                    log.l_mqevent = haddleing.l_mqevent;
                    log.l_agreement_type = haddleing.l_agreement_type;
                    log.l_device_remark = haddleing.l_device_remark;
                    log.l_gateway_code = haddleing.l_gateway_code;
                    log.l_gateway_deviceguid = haddleing.l_gateway_deviceguid;
                    log.l_repeat_count = haddleing.l_repeat_count;
                    log.l_repeat_count_interval = haddleing.l_repeat_count_interval;
                    log.l_source = haddleing.l_source;
                    log.l_return_msg = result;
                    log.l_return_time = DateTime.Now;
                    log.l_device_model_code = haddleing.l_device_model_code;
                    log.l_parameter = haddleing.l_parameter;
                    ef.iot_device_command_log.AddAsync(log);
                    ef.SaveChanges();

                    ef = new EFYihongIotContext();
                    ef.iot_device_command_haddleing.Remove(haddleing);
                    ef.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.ToString());
                return false;
            }
            return true;
        }
       

        /// <summary>
        /// 执行日志
        /// </summary>
        /// <param name="commandLogModel"></param>
        /// <returns></returns>
        public void writeCommandHandleing(CommandLogModel commandLogModel)
        {

            //是否开启mq日志记录，保护emmc寿命
            if (logSave == "false")
            {
                return;
            }
            try
            {
                EFYihongIotContext ef = new EFYihongIotContext();
                iot_device_command_haddleing log = new iot_device_command_haddleing();
                log.l_guid = commandLogModel.guid;
                log.l_d_guid = commandLogModel.d_guid;
                log.l_content = commandLogModel.content;
                log.l_key = commandLogModel.key;
                log.l_name = commandLogModel.name;
                log.l_status_remark = commandLogModel.status_remark;
                log.l_status = commandLogModel.status;
                log.l_mqevent = commandLogModel.mqevent;
                log.l_agreement_type = commandLogModel.agreementType;
                log.l_device_remark = commandLogModel.device_remark;
                log.l_gateway_code = commandLogModel.gatewayCode;
                log.l_gateway_deviceguid = commandLogModel.gatewayDeviceGuid;
                log.l_repeat_count = commandLogModel.repeatCount;
                log.l_repeat_count_interval = commandLogModel.repeatCountInterval;
                log.l_parameter = commandLogModel.parameter;
                log.l_device_model_code = commandLogModel.deviceModelCode;
                log.l_source = commandLogModel.source;
                ef.iot_device_command_haddleing.AddAsync(log);
                ef.SaveChanges();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
        /// <summary>
        /// 发送指令到网关
        /// </summary>
        /// <param name="dguid"></param>
        /// <param name="commandKey"></param>
        /// <param name="groupGuid"></param>
        /// <param name="repeat">重复执行次数</param>
        /// <returns></returns>

        public string sendCommandToGateWay(string dguid, string commandKey, string source)
        {
            return sendCommandToGateWayDo(dguid, commandKey, source, "", "", 1, 10000);
        }
        public string sendCommandToGateWay(string dguid, string commandKey, string source, string groupGuid, int repeatCount, int repeatCountInterval)
        {

            return sendCommandToGateWayDo(dguid, commandKey, source, "", groupGuid, repeatCount, repeatCountInterval);
        }


        public string sendCommandToGateWayByCommand(string dguid, string commandKey, string source, string command = "")
        {
            return sendCommandToGateWayDo(dguid, commandKey, source, command, "", 1, 10000);

        }
        public string sendCommandToGateWayDo(string dguid, string commandKey, string source, string command, string groupGuid, int repeatCount, int repeatCountInterval)
        {
            try
            {
                EFYihongIotContext ef = new EFYihongIotContext();

                iot_device device = new DBIotDeviceCache().getClientDeviceByCache(dguid);


                iot_device_command iot_Device_Command = new DBIotDeviceCommandCache().getCommandByCache(device.d_model_guid, commandKey);
                if (iot_Device_Command == null)
                {
                    return "";
                }
                iot_device_model_type model_Type = new DBIotDeviceModelTypeCache().getModelTypeByDeviceCache(dguid);
                if (model_Type.t_code == "1008")
                {//模拟gpio状态值，不需要传到网关处理，直接写入值
                    new ServiceCloudDeviceValueLog().writeSensorlog(dguid, "status", iot_Device_Command.dc_content, iot_Device_Command.dc_name);
                    Task.Run(() =>
                    {   //模拟gpio状态值 没有真正下发到网关，或者回调，所以这里要特别处理触发
                        //条件处理
                        new ServiceCloudLinkageCondition().linkageConditionAutoRun(dguid);
                    });
                    return "";
                }
                iot_device_gateway iot_Device_Gateway = new DBIotDeviceGateWayCache().getGateWayByCache(device.d_gw_d_guid);// ef.iot_device_gateway.Where(c => c.gw_d_guid == iot_Device.d_gw_d_guid).FirstOrDefault();

                string parameter = device.d_parameter;
                //判断设备参数类型
                if (!string.IsNullOrEmpty(command))
                {
                    //设备初始化需要的参数，修改波特率，寄存器地址
                    parameter = command;
                }

                //写日志
                CommandLogModel commandLogModel = new CommandLogModel();
                commandLogModel.guid = Guid.NewGuid().ToString();
                commandLogModel.d_guid = device.d_guid;
                commandLogModel.deviceModelCode = new DBIotDeviceModelCache().getModelByDeviceCache(dguid).m_code;// ef.iot_device_model.Where(c => c.m_guid == iot_Device.d_model_guid).FirstOrDefault().m_code;
                commandLogModel.content = iot_Device_Command.dc_content;
                commandLogModel.key = commandKey;
                commandLogModel.name = iot_Device_Command.dc_name;
                commandLogModel.status_remark = "待处理";
                commandLogModel.status = 1;
                commandLogModel.mqevent = MQEventEnum.Event_HandleCommand;
                commandLogModel.gatewayCode = iot_Device_Gateway.gw_code;
                commandLogModel.gatewayDeviceGuid = iot_Device_Gateway.gw_d_guid;
                commandLogModel.agreementType = iot_Device_Command.dc_agreement_type;
                commandLogModel.device_remark = device.d_name;
                commandLogModel.parameter = parameter;
                commandLogModel.groupGuid = groupGuid;
                commandLogModel.repeatCount = repeatCount;
                commandLogModel.repeatCountInterval = repeatCountInterval;
                commandLogModel.source = source;

                Task.Run(() =>
                {
                    new ServiceSendMQ().sendCommandToGateWay(commandLogModel);//下发到网关
                    new ServiceCloudDeviceCommand().writeCommandHandleing(commandLogModel);//写操作记录
                });
                ef.Dispose();
                return commandLogModel.guid;
            }
            catch (Exception ex)
            {
                new DBIotSystemLogError().addSystemLogError(dguid, dguid, commandKey + "--" + ex.Message);

                Console.WriteLine(ex.ToString());
            }
            return "";
        }
       
    }
}